home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cctools / libstuff / arch.c < prev    next >
C/C++ Source or Header  |  1994-06-03  |  10KB  |  312 lines

  1. #include "string.h"
  2. #include <mach/mach.h>
  3. #include "stuff/arch.h"
  4.  
  5. /*
  6.  * The array of all currently know architecture flags (terminated with an entry
  7.  * with all zeros).  Pointer to this returned with get_arch_flags().
  8.  */
  9. static const struct arch_flag arch_flags[] = {
  10.     { "any",    CPU_TYPE_ANY,      CPU_SUBTYPE_MULTIPLE },
  11.     { "little",    CPU_TYPE_ANY,      CPU_SUBTYPE_LITTLE_ENDIAN },
  12.     { "big",    CPU_TYPE_ANY,      CPU_SUBTYPE_BIG_ENDIAN },
  13.     /* architecture families */
  14.     { "m68k",   CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL },
  15.     { "m98k",   CPU_TYPE_MC98000, CPU_SUBTYPE_MC98000_ALL },
  16.     { "m88k",   CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL },
  17.     { "i386",   CPU_TYPE_I386,    CPU_SUBTYPE_I386_ALL },
  18.     { "i860",   CPU_TYPE_I860,    CPU_SUBTYPE_I860_ALL },
  19.     { "hppa",   CPU_TYPE_HPPA,    CPU_SUBTYPE_HPPA_ALL },
  20.     { "sparc",    CPU_TYPE_SPARC,   CPU_SUBTYPE_SPARC_ALL },
  21.     /* specific architecture implementations */
  22.     { "m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY },
  23.     { "m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040 },
  24.     { "i486",   CPU_TYPE_I386,    CPU_SUBTYPE_486 },
  25.     { "i486SX", CPU_TYPE_I386,    CPU_SUBTYPE_486SX },
  26.     { "i586",   CPU_TYPE_I386,    CPU_SUBTYPE_586 },
  27.     { "i586SX", CPU_TYPE_I386,    CPU_SUBTYPE_586SX },
  28.     { "hppa7100LC", CPU_TYPE_HPPA,  CPU_SUBTYPE_HPPA_7100LC },
  29.     { NULL,    0,          0 }
  30. };
  31.  
  32. /*
  33.  * get_arch_from_flag() is passed a name of an architecture flag and returns
  34.  * zero if that flag is not known and non-zero if the flag is known.
  35.  * If the pointer to the arch_flag is not NULL it is filled in with the
  36.  * arch_flag struct that matches the name.
  37.  */
  38. int
  39. get_arch_from_flag(
  40. char *name,
  41. struct arch_flag *arch_flag)
  42. {
  43.     unsigned long i;
  44.  
  45.     for(i = 0; arch_flags[i].name != NULL; i++){
  46.         if(strcmp(arch_flags[i].name, name) == 0){
  47.         if(arch_flag != NULL)
  48.             *arch_flag = arch_flags[i];
  49.         return(1);
  50.         }
  51.     }
  52.     if(arch_flag != NULL)
  53.         memset(arch_flag, '\0', sizeof(struct arch_flag));
  54.     return(0);
  55. }
  56.  
  57. /*
  58.  * get_arch_from_host() gets the architecture from the host this is running on
  59.  * and returns zero if the architecture is not known and zero if the
  60.  * architecture is known.  If the parameters family_arch_flag and
  61.  * specific_arch_flag are not NULL they get fill in with the family
  62.  * architecture and specific architecure for the host.  If the architecture
  63.  * is unknown and the parameters are not NULL then all fields are set to zero.
  64.  */
  65. int
  66. get_arch_from_host(
  67. struct arch_flag *family_arch_flag,
  68. struct arch_flag *specific_arch_flag)
  69. {
  70.     struct host_basic_info host_basic_info;
  71.     unsigned int count;
  72.     kern_return_t r;
  73.  
  74.     if(family_arch_flag != NULL)
  75.         memset(family_arch_flag, '\0', sizeof(struct arch_flag));
  76.     if(specific_arch_flag != NULL)
  77.         memset(specific_arch_flag, '\0', sizeof(struct arch_flag));
  78.  
  79.     count = HOST_BASIC_INFO_COUNT;
  80.     if((r = host_info(host_self(), HOST_BASIC_INFO,
  81.               (host_info_t)(&host_basic_info),
  82.               &count)) != KERN_SUCCESS)
  83.         return(0);
  84.  
  85.     if(family_arch_flag != NULL){
  86.         family_arch_flag->cputype = host_basic_info.cpu_type;
  87.     }
  88.     if(specific_arch_flag != NULL){
  89.         specific_arch_flag->cputype = host_basic_info.cpu_type;
  90.         specific_arch_flag->cpusubtype = host_basic_info.cpu_subtype;
  91.     }
  92.     switch(host_basic_info.cpu_type){
  93.     case CPU_TYPE_MC680x0:
  94.         switch(host_basic_info.cpu_subtype){
  95.         case CPU_SUBTYPE_MC680x0_ALL:
  96.         case CPU_SUBTYPE_MC68030_ONLY:
  97.         if(family_arch_flag != NULL){
  98.             family_arch_flag->name = "m68k";
  99.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
  100.         }
  101.         if(specific_arch_flag != NULL){
  102.             specific_arch_flag->name = "m68030";
  103.             /* 
  104.              * There is a "bug" in the kernel for compatiblity that on
  105.              * an 030 machine host_info() returns cpusubtype
  106.              * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
  107.              */
  108.             specific_arch_flag->cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
  109.         }
  110.         return(1);
  111.         case CPU_SUBTYPE_MC68040:
  112.         if(family_arch_flag != NULL){
  113.             family_arch_flag->name = "m68k";
  114.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
  115.         }
  116.         if(specific_arch_flag != NULL)
  117.             specific_arch_flag->name = "m68040";
  118.         return(1);
  119.         }
  120.         break;
  121.     case CPU_TYPE_MC98000:
  122.         switch(host_basic_info.cpu_subtype){
  123.         case CPU_SUBTYPE_MC98000_ALL:
  124.         if(family_arch_flag != NULL){
  125.             family_arch_flag->name = "m98k";
  126.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC98000_ALL;
  127.         }
  128.         if(specific_arch_flag != NULL)
  129.             specific_arch_flag->name = "m98k";
  130.         return(1);
  131.         }
  132.         break;
  133.     case CPU_TYPE_MC88000:
  134.         switch(host_basic_info.cpu_subtype){
  135.         case CPU_SUBTYPE_MC88000_ALL:
  136.         case CPU_SUBTYPE_MC88110:
  137.         if(family_arch_flag != NULL){
  138.             family_arch_flag->name = "m88k";
  139.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC88000_ALL;
  140.         }
  141.         if(specific_arch_flag != NULL)
  142.             specific_arch_flag->name = "m88k";
  143.         return(1);
  144.         }
  145.         break;
  146.     case CPU_TYPE_I386:
  147.         switch(host_basic_info.cpu_subtype){
  148.         case CPU_SUBTYPE_I386_ALL:
  149.         /* case CPU_SUBTYPE_386: same value as above */
  150.         if(family_arch_flag != NULL){
  151.             family_arch_flag->name = "i386";
  152.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  153.         }
  154.         if(specific_arch_flag != NULL)
  155.             specific_arch_flag->name = "i386";
  156.         return(1);
  157.         case CPU_SUBTYPE_486:
  158.         if(family_arch_flag != NULL){
  159.             family_arch_flag->name = "i386";
  160.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  161.         }
  162.         if(specific_arch_flag != NULL)
  163.             specific_arch_flag->name = "i486";
  164.         return(1);
  165.         case CPU_SUBTYPE_486SX:
  166.         if(family_arch_flag != NULL){
  167.             family_arch_flag->name = "i386";
  168.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  169.         }
  170.         if(specific_arch_flag != NULL)
  171.             specific_arch_flag->name = "i486SX";
  172.         return(1);
  173.         case CPU_SUBTYPE_586:
  174.         if(family_arch_flag != NULL){
  175.             family_arch_flag->name = "i386";
  176.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  177.         }
  178.         if(specific_arch_flag != NULL)
  179.             specific_arch_flag->name = "i586";
  180.         return(1);
  181.         case CPU_SUBTYPE_586SX:
  182.         if(family_arch_flag != NULL){
  183.             family_arch_flag->name = "i386";
  184.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  185.         }
  186.         if(specific_arch_flag != NULL)
  187.             specific_arch_flag->name = "i586SX";
  188.         return(1);
  189.         }
  190.         break;
  191.     case CPU_TYPE_I860:
  192.         switch(host_basic_info.cpu_subtype){
  193.         case CPU_SUBTYPE_I860_ALL:
  194.         case CPU_SUBTYPE_I860_860:
  195.         if(family_arch_flag != NULL){
  196.             family_arch_flag->name = "i860";
  197.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I860_ALL;
  198.         }
  199.         if(specific_arch_flag != NULL)
  200.             specific_arch_flag->name = "i860";
  201.         return(1);
  202.         }
  203.         break;
  204.     case CPU_TYPE_HPPA:
  205.         switch(host_basic_info.cpu_subtype){
  206.         case CPU_SUBTYPE_HPPA_ALL:
  207.         if(family_arch_flag != NULL){
  208.             family_arch_flag->name = "hppa";
  209.             family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
  210.         }
  211.         if(specific_arch_flag != NULL)
  212.             specific_arch_flag->name = "hppa";
  213.         return(1);
  214.         case CPU_SUBTYPE_HPPA_7100LC:
  215.         if(family_arch_flag != NULL){
  216.             family_arch_flag->name = "hppa";
  217.             family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
  218.         }
  219.         if(specific_arch_flag != NULL)
  220.             specific_arch_flag->name = "hppa7100LC";
  221.         return(1);
  222.           
  223.         }
  224.         break;
  225.     case CPU_TYPE_SPARC:
  226.         switch(host_basic_info.cpu_subtype){
  227.         case /*CPU_SUBTYPE_SPARC_ALL*/0:
  228.         if(family_arch_flag != NULL){
  229.             family_arch_flag->name = "sparc";
  230.             family_arch_flag->cpusubtype = CPU_SUBTYPE_SPARC_ALL;
  231.         }
  232.         if(specific_arch_flag != NULL)
  233.             specific_arch_flag->name = "sparc";
  234.         return(1);
  235.         }
  236.         break;
  237.     }
  238.     return(0);
  239. }
  240.  
  241. /*
  242.  * get_arch_flags() returns a pointer to an array of all currently know
  243.  * architecture flags (terminated with an entry with all zeros).
  244.  */
  245. const struct arch_flag *
  246. get_arch_flags(
  247. void)
  248. {
  249.     return(arch_flags);
  250. }
  251.  
  252. /*
  253.  * get_arch_name_from_types() returns the name of the architecture for the
  254.  * specified cputype and cpusubtype if known.  If unknown it returns a pointer
  255.  * to the string "unknown".
  256.  */
  257. const char *
  258. get_arch_name_from_types(
  259. cpu_type_t cputype,
  260. cpu_subtype_t cpusubtype)
  261. {
  262.     unsigned long i;
  263.  
  264.     for(i = 0; arch_flags[i].name != NULL; i++){
  265.         if(arch_flags[i].cputype == cputype &&
  266.            arch_flags[i].cpusubtype == cpusubtype)
  267.         return(arch_flags[i].name);
  268.     }
  269.     return("unknown");
  270. }
  271.  
  272. /*
  273.  * get_arch_family_from_cputype() returns the family architecture for the
  274.  * specified cputype if known.  If unknown it returns NULL.
  275.  */
  276. const struct arch_flag *
  277. get_arch_family_from_cputype(
  278. cpu_type_t cputype)
  279. {
  280.     unsigned long i;
  281.  
  282.     for(i = 0; arch_flags[i].name != NULL; i++){
  283.         if(arch_flags[i].cputype == cputype)
  284.         return(arch_flags + i);
  285.     }
  286.     return(NULL);
  287. }
  288.  
  289. /*
  290.  * get_byte_sex_from_flag() returns the byte sex of the architecture for the
  291.  * specified cputype and cpusubtype if known.  If unknown it returns
  292.  * UNKNOWN_BYTE_SEX.  If the bytesex can be determined directly as in the case
  293.  * of reading a magic number from a file that should be done and this routine
  294.  * should not be used as it could be out of date.
  295.  */
  296. enum byte_sex
  297. get_byte_sex_from_flag(
  298. const struct arch_flag *flag)
  299. {
  300.    if(flag->cputype == CPU_TYPE_MC680x0 ||
  301.       flag->cputype == CPU_TYPE_MC88000 ||
  302.       flag->cputype == CPU_TYPE_MC98000 ||
  303.       flag->cputype == CPU_TYPE_HPPA ||
  304.       flag->cputype == CPU_TYPE_SPARC ||
  305.       flag->cputype == CPU_TYPE_I860)
  306.         return BIG_ENDIAN_BYTE_SEX;
  307.     else if(flag->cputype == CPU_TYPE_I386)
  308.         return LITTLE_ENDIAN_BYTE_SEX;
  309.     else
  310.         return UNKNOWN_BYTE_SEX;
  311. }
  312.